Stop, Collaborate, and Listen: An ERGM Analysis of School Leader Networks

PREPARE

This study was completed as part of the summer 2021 Social Network Analysis in Education course (ECI 589) at North Carolina State University. The course is the last of the series of courses offered as part of the Learning Analytics Certificate Program.

The Rmarkdown file can be downloaded from the code folding control button in the upper right hand of this page. The full R Studio project can be access via this Github repository. The text for this course is Social Network Analysis and Education: Theory, Methods & Applications from Carolan (2014). The data for this project can be obtained from this text’s companion site.

Context

This independent analysis uses data from Daly’s Network of School Leaders presented in Chapter 3 of Carolan (2014). These data were collected at two school districts over 3 consecutive years and include:

  • individual demographics (e.g., gender, ethnicity, etc)
  • network relationships (e.g., collaboration, confidential, etc)
  • frequency of interactions with others on a four-point scale ranging from 1 (the least frequent) to 4 (1–2 times a week)
  • 18 efficacy items based on the Principal Efficacy Scale used in the Daly et al. (2011) and Tschannen-Moran and Gareis’s (2004) studies and rated on a 9-point Likert scale ranging from 1 (None at all) to 9 (A great deal)
  • 8 trust items rated on a 7-point Likert scale ranging from 1 (Strongly disagree) to 7 (Strongly agree) modified from Tschannen-Moran and Hoy (2003).

Guiding Questions and Methods

This study focuses on the confidential exchanges between school leaders in year 1 and is framed by the following questions:

  1. Does gender or some other individual attribute predict confidential exchanges between school leaders?

  2. Do school leaders prefer to confide in others at the same level of leadership (i.e., school or district)?

The analysis employs Exponential-family Random Graph Models (ERGMs) to answer these questions.

R Packages

The following R packages were used for the analyses carried out in this study.

library(readxl)
library(here)
library(tidyverse)
library(igraph)
library(tidygraph)
library(ggraph)
library(deldir)
library(statnet)

Import the Data

The data were imported from the Carolan (2014) text’s Chapter 9 Excel files provided on the text companion site. There are two Excel files:

  • School_Leaders_Data_Chapter_9_e.xlsx provides the individual demographic data for the 43 school leaders in the network.
  • School_Leaders_Data_Chapter_9_c.xlsx provides the adjacency matrix reports on “confidential exchange” ties of these 43 school leaders in year 1 of the study.
leader_nodes <- read_excel(here("Presentation",
                                "data",
                                "School_Leaders_Data_Chapter_9_e.xlsx"),
                           col_types = c("text", "numeric", 
                                         "numeric", "numeric", "numeric"))

leader_matrix <- read_excel(here("Presentation",
                                 "data","School_Leaders_Data_Chapter_9_c.xlsx"), 
                            col_names = FALSE)

WRANGLE

I’ve got all my libraries loaded and the data has been imported. So, let’s go wrangle some data…

Dichotomize the Matrix

Dichotomizing is recoding edge values to 1s and 0s so that the valued matrix is a binary matrix. To accomplish this, I first create the matrix object.

leader_matrix <- leader_matrix %>%
  as.matrix()

Then I dichotomize it by setting less frequent ties to 0 and more frequent ties to 1.

leader_matrix[leader_matrix <= 2] <- 0

leader_matrix[leader_matrix >= 3] <- 1

Next, I add the node names as row and column names for the purpose of generating an edge-list for this network.

rownames(leader_matrix) <- leader_nodes$ID
colnames(leader_matrix) <- leader_nodes$ID

Create Network Graph

In order to extract the edge list, I use the matrix to create an igraph graph object.

adjacency_matrix <- graph.adjacency(leader_matrix,
                                    diag = FALSE)

class(adjacency_matrix)
## [1] "igraph"

Edge list

All this set up allows me to extract the edge-list from the igraph graph object. The result is a set of 25 ties between the school leaders.

leader_edges <- get.data.frame(adjacency_matrix)


kable(leader_edges)
from to
7 33
9 5
9 17
10 8
11 40
14 42
19 37
20 10
20 23
21 40
22 29
24 27
24 34
27 24
27 34
28 18
28 37
32 24
35 11
35 21
36 29
38 37
39 19
40 37
42 8

Network Graph

With an edge list, I can now create a network graph object using my edges and nodes. This is shown in the following code chunk.

leader_graph <- tbl_graph(edges = leader_edges,
                          nodes = leader_nodes,
                          directed = TRUE)

leader_graph
## # A tbl_graph: 43 nodes and 25 edges
## #
## # A directed simple graph with 21 components
## #
## # Node Data: 43 x 5 (active)
##   ID    EFFICACY TRUST `DISTRICT/SITE`  MALE
##   <chr>    <dbl> <dbl>           <dbl> <dbl>
## 1 1         6.06  4                  1     0
## 2 2         6.56  5.63               1     0
## 3 3         7.39  4.63               1     0
## 4 4         4.89  4                  1     0
## 5 5         6.06  5.75               0     1
## 6 6         7.39  4.38               0     0
## # … with 37 more rows
## #
## # Edge Data: 25 x 2
##    from    to
##   <int> <int>
## 1     7    33
## 2     9     5
## 3     9    17
## # … with 22 more rows

As you can see, the result is a directed graph with 43 nodes (the school leaders) and 25 edges. Since there are fewer edges than nodes, it should be safe to assume that some school leaders either did not engage in confidential exchanges in year 1 or, if they did, they did so very infrequently.

EXPLORE

The following sections will provide some basic summary statistics of these data and a sociogram for visualizing the network.

Node degrees

Before getting the summary statisitics, I calculate the in_degree and out_degree of the nodes with the following code.

## # A tbl_graph: 43 nodes and 25 edges
## #
## # A directed simple graph with 21 components
## #
## # Node Data: 43 x 7 (active)
##   ID    EFFICACY TRUST `DISTRICT/SITE`  MALE in_degree out_degree
##   <chr>    <dbl> <dbl>           <dbl> <dbl>     <dbl>      <dbl>
## 1 1         6.06  4                  1     0         0          0
## 2 2         6.56  5.63               1     0         0          0
## 3 3         7.39  4.63               1     0         0          0
## 4 4         4.89  4                  1     0         0          0
## 5 5         6.06  5.75               0     1         1          0
## 6 6         7.39  4.38               0     0         0          0
## # … with 37 more rows
## #
## # Edge Data: 25 x 2
##    from    to
##   <int> <int>
## 1     7    33
## 2     9     5
## 3     9    17
## # … with 22 more rows

Node Measures

With the in_degree and out_degree added to the network’s measures, I can get the summary of these measures.

##       ID               EFFICACY         TRUST       DISTRICT.SITE   
##  Length:43          Min.   :4.610   Min.   :3.630   Min.   :0.0000  
##  Class :character   1st Qu.:5.670   1st Qu.:4.130   1st Qu.:0.0000  
##  Mode  :character   Median :6.780   Median :4.780   Median :0.0000  
##                     Mean   :6.649   Mean   :4.783   Mean   :0.4186  
##                     3rd Qu.:7.470   3rd Qu.:5.440   3rd Qu.:1.0000  
##                     Max.   :8.500   Max.   :5.880   Max.   :1.0000  
##       MALE          in_degree        out_degree    
##  Min.   :0.0000   Min.   :0.0000   Min.   :0.0000  
##  1st Qu.:0.0000   1st Qu.:0.0000   1st Qu.:0.0000  
##  Median :0.0000   Median :0.0000   Median :0.0000  
##  Mean   :0.4419   Mean   :0.5814   Mean   :0.5814  
##  3rd Qu.:1.0000   3rd Qu.:1.0000   3rd Qu.:1.0000  
##  Max.   :1.0000   Max.   :4.0000   Max.   :2.0000

Breaking it Down: School and District Level Descriptives

The following sections provide descriptives statistics for the in degree, out degree, trust, and efficacy of the network delineated by level of administration (i.e., school or district level).

In Degree

DISTRICT.SITE n mean sd
0 25 0.4400000 0.5830952
1 18 0.7777778 1.1659662

Out Degree

DISTRICT.SITE n mean sd
0 25 0.6000000 0.7071068
1 18 0.5555556 0.7838234

Trust

DISTRICT.SITE n mean sd
0 25 4.9044 0.7191666
1 18 4.6150 0.6880514

Efficacy

DISTRICT.SITE n mean sd
0 25 7.022000 0.9534149
1 18 6.131667 1.1151906

Comparison to Carolan (2014)

Examining these descriptive statistics, it appears I have successfully replicated the results shown in Table 9.1 of Carolan (2014) for school leaders confidential exchanges in year 1. Table 9.1 is shown below.

Visualize the Network

As you see below, visualizing the network for year 1 looks quite a bit different from the year 3 network. There are far fewer confidential exchanges in year 1. Additionally, coloring the nodes by gender reveals that the groupings of confidential exchanges don’t appear to consist of a single gender. Moreover, the node shapes (square for district-level and circle for school-level leader) appear to indicate that the groupings consist of either a majority of district-level leaders or school-level leaders. This suggests that administration level may be important in year 1 confidential networks. I’ll take this into consideration as I use ERGM to model the network data.

ggraph(leader_measures, layout = "fr") + 
  geom_node_point(aes(size = out_degree,
                      colour = factor(MALE),
                      fill = factor(MALE)),
                  shape = node_measures$DISTRICT.SITE + 21, show.legend = TRUE) +
  geom_node_text(aes(label = ID,
                     size = 1.5), 
                     repel=TRUE, show.legend = FALSE) +
  geom_edge_link(arrow = arrow(length = unit(1, 'mm')), 
                 end_cap = circle(2, 'mm'),
                 alpha = .3) + 
  theme_graph()

MODEL

Setting up to perform an ERGM, I create a network object with these edges and nodes. The result is a directed network with 43 nodes (school leaders) and 25 edges.

##  Network attributes:
##   vertices = 43 
##   directed = TRUE 
##   hyper = FALSE 
##   loops = FALSE 
##   multiple = FALSE 
##   bipartite = FALSE 
##   total edges= 25 
##     missing edges= 0 
##     non-missing edges= 25 
## 
##  Vertex attribute names: 
##     DISTRICT/SITE EFFICACY MALE TRUST vertex.names 
## 
## No edge attributes

ERGM

To address my guiding questions, I ran the ERGM with all the individual attributes as well as the geometrically-weighed edgewise shared partner (GWESP) term for transitivity.

## Call:
## ergm(formula = leader_network ~ edges + mutual + gwesp(0.25, 
##     fixed = T) + nodefactor("MALE") + nodecov("EFFICACY") + nodecov("TRUST") + 
##     nodematch("DISTRICT/SITE"))
## 
## Monte Carlo Maximum Likelihood Results:
## 
##                         Estimate Std. Error MCMC % z value Pr(>|z|)   
## edges                    -6.4576     2.1573      0  -2.993  0.00276 **
## mutual                    0.9490     1.1461      0   0.828  0.40763   
## gwesp.fixed.0.25          1.1949     0.4299      0   2.779  0.00544 **
## nodefactor.MALE.1         0.3721     0.2629      0   1.415  0.15706   
## nodecov.EFFICACY         -0.1263     0.1220      0  -1.035  0.30046   
## nodecov.TRUST             0.2381     0.1812      0   1.314  0.18877   
## nodematch.DISTRICT/SITE   1.5357     0.5310      0   2.892  0.00383 **
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
##      Null Deviance: 2503.6  on 1806  degrees of freedom
##  Residual Deviance:  241.8  on 1799  degrees of freedom
##  
## AIC: 255.8  BIC: 294.3  (Smaller is better. MC Std. Err. = 0.04752)

While gender, efficacy, and trust do not appear to be significant predictors of confidential exchanges in year 1, the GWESP and the level of administration terms are significant is this model.

Model Fit

Let’s just take a look at the fit of this model using the gof() function and running some mcmc.diagnostics().

Goodness of Fit

Overall, the results of the gof() function show that this model fits reasonably well. That is, with the exception of the mutual term which isn’t surprising given the p-value.

my_ergm_gof <- gof(my_ergm)

plot(my_ergm_gof)

MCMC Diagnostics

Next, I examine the Monte-Carlo Markov Chain (MCMC) diagnostics for this model.

mcmc.diagnostics(my_ergm)
## Sample statistics summary:
## 
## Iterations = 472064:8388608
## Thinning interval = 1024 
## Number of chains = 1 
## Sample size per chain = 7732 
## 
## 1. Empirical mean and standard deviation for each variable,
##    plus standard error of the mean:
## 
##                            Mean     SD Naive SE Time-series SE
## edges                    1.5210  7.407  0.08424        0.21280
## mutual                   0.3341  1.710  0.01945        0.05852
## gwesp.fixed.0.25         1.2339  5.297  0.06024        0.20170
## nodefactor.MALE.1        1.8862 10.480  0.11918        0.32189
## nodecov.EFFICACY        20.1004 96.883  1.10180        2.70287
## nodecov.TRUST           15.4958 75.448  0.85802        2.24566
## nodematch.DISTRICT/SITE  1.3991  7.057  0.08025        0.20862
## 
## 2. Quantiles for each variable:
## 
##                            2.5%    25%   50%   75%  97.5%
## edges                    -10.00  -4.00  1.00  5.00  19.00
## mutual                    -1.00  -1.00  0.00  1.00   5.00
## gwesp.fixed.0.25          -2.00  -2.00 -1.00  2.00  17.88
## nodefactor.MALE.1        -14.00  -5.00  0.00  7.00  29.00
## nodecov.EFFICACY        -131.70 -47.09  8.07 71.95 254.90
## nodecov.TRUST            -99.53 -36.62  5.14 53.83 201.37
## nodematch.DISTRICT/SITE   -9.00  -3.00  0.00  5.00  19.00
## 
## 
## Are sample statistics significantly different from observed?
##                   edges       mutual gwesp.fixed.0.25 nodefactor.MALE.1
## diff.      1.520952e+00 3.340662e-01     1.233867e+00      1.886187e+00
## test stat. 7.147335e+00 5.708596e+00     6.117478e+00      5.859790e+00
## P-val.     8.847909e-13 1.139116e-08     9.506787e-10      4.634516e-09
##            nodecov.EFFICACY nodecov.TRUST nodematch.DISTRICT/SITE
## diff.          2.010037e+01  1.549576e+01            1.399121e+00
## test stat.     7.436689e+00  6.900326e+00            6.706476e+00
## P-val.         1.032403e-13  5.188316e-12            1.993809e-11
##            Overall (Chi^2)
## diff.                   NA
## test stat.    1.604129e+02
## P-val.        1.037157e-30
## 
## Sample statistics cross-correlations:
##                             edges    mutual gwesp.fixed.0.25 nodefactor.MALE.1
## edges                   1.0000000 0.7055074        0.7546630         0.9188177
## mutual                  0.7055074 1.0000000        0.8517864         0.7327079
## gwesp.fixed.0.25        0.7546630 0.8517864        1.0000000         0.7927996
## nodefactor.MALE.1       0.9188177 0.7327079        0.7927996         1.0000000
## nodecov.EFFICACY        0.9960890 0.6944590        0.7421291         0.9117900
## nodecov.TRUST           0.9966234 0.7218665        0.7735616         0.9221310
## nodematch.DISTRICT/SITE 0.9601530 0.7273599        0.7744386         0.8945465
##                         nodecov.EFFICACY nodecov.TRUST nodematch.DISTRICT/SITE
## edges                          0.9960890     0.9966234               0.9601530
## mutual                         0.6944590     0.7218665               0.7273599
## gwesp.fixed.0.25               0.7421291     0.7735616               0.7744386
## nodefactor.MALE.1              0.9117900     0.9221310               0.8945465
## nodecov.EFFICACY               1.0000000     0.9936731               0.9570709
## nodecov.TRUST                  0.9936731     1.0000000               0.9600324
## nodematch.DISTRICT/SITE        0.9570709     0.9600324               1.0000000
## 
## Sample statistics auto-correlation:
## Chain 1 
##              edges    mutual gwesp.fixed.0.25 nodefactor.MALE.1
## Lag 0    1.0000000 1.0000000        1.0000000         1.0000000
## Lag 1024 0.3964813 0.6385957        0.7739151         0.4775483
## Lag 2048 0.3222917 0.5407671        0.6611434         0.4038687
## Lag 3072 0.2788877 0.4588149        0.5608703         0.3473963
## Lag 4096 0.2375864 0.3892603        0.4783085         0.2989556
## Lag 5120 0.1872085 0.3287127        0.4041185         0.2441561
##          nodecov.EFFICACY nodecov.TRUST nodematch.DISTRICT/SITE
## Lag 0           1.0000000     1.0000000               1.0000000
## Lag 1024        0.3785797     0.4246852               0.4250971
## Lag 2048        0.3076251     0.3467390               0.3485443
## Lag 3072        0.2643215     0.2978761               0.2901923
## Lag 4096        0.2243780     0.2554762               0.2549752
## Lag 5120        0.1752310     0.2044617               0.2017691
## 
## Sample statistics burn-in diagnostic (Geweke):
## Chain 1 
## 
## Fraction in 1st window = 0.1
## Fraction in 2nd window = 0.5 
## 
##                   edges                  mutual        gwesp.fixed.0.25 
##                 -0.6193                 -0.2562                 -0.2602 
##       nodefactor.MALE.1        nodecov.EFFICACY           nodecov.TRUST 
##                 -0.3573                 -0.6116                 -0.6141 
## nodematch.DISTRICT/SITE 
##                 -0.5583 
## 
## Individual P-values (lower = worse):
##                   edges                  mutual        gwesp.fixed.0.25 
##               0.5356962               0.7978305               0.7946715 
##       nodefactor.MALE.1        nodecov.EFFICACY           nodecov.TRUST 
##               0.7208672               0.5408310               0.5391571 
## nodematch.DISTRICT/SITE 
##               0.5766220 
## Joint P-value (lower = worse):  0.7492824 .

## 
## MCMC diagnostics shown here are from the last round of simulation, prior to computation of final parameter estimates. Because the final estimates are refinements of those used for this simulation run, these diagnostics may understate model performance. To directly assess the performance of the final model on in-model statistics, please use the GOF command: gof(ergmFitObject, GOF=~model).

Overall, the diagnostics are a little difficult to interpret but also appear to indicate that the model is a reasonable fit.

COMMUNICATE

This study was framed by the following questions:

  1. Does gender or some other individual attribute predict confidential exchanges between school leaders?

  2. Do school leaders prefer to confide in others at the same level of leadership (i.e., school or district)?

Answering question 1 based on the results in the previous sections, it would appear that the only individual attribute that predicts confidential exchanges in year 1 is whether a school leader is at the school or district level. Moreover, confidential exchanges also appear to be significantly impacted by transitivity represented by the geometrically-weighed edgewise shared partner term (i.e., “friend of a friend” phenomenon). These results suggest that, at least for year 1, school leaders appear to prefer to confide in others at the same level of administration.

ABOUT THE AUTHOR

Jennifer Houchins is Director of Technology Programs at the Friday Institute for Eductional Innovation and a doctoral candidate in Learning Design and Technology at North Carolina State University. Her research examines students’ use of computational thinking and the effective use of instructional technology to deepen conceptual understanding in both formal and informal K-12 learning environments.

You can learn more about Jennifer and her work by visiting her website. You can also follow her on : @TooSweetGeek

GET THE PROJECT CODE

If you’d like to learn more about the techniques used in this analysis (including the Rmarkdown techniques used in the write up), then you can get the R project from my Github repo:

https://github.com/jennhouchins/ECI589-SNA

THE END OF AN ERA

This is the bittersweet end of my coursework in the Learning Analytics Certificate Program at NC State (and ultimately, my doctoral program coursework as well). I have enjoyed these courses and the learning community I’ve gained in them, but am very much looking forward to completely my dissertation and graduating.

REFERENCES

Carolan, Brian. 2014. “Social Network Analysis and Education: Theory, Methods & Applications.” https://doi.org/10.4135/9781452270104.
LS0tCnRpdGxlOiAiU3RvcCwgQ29sbGFib3JhdGUsIGFuZCBMaXN0ZW46IEFuIEVSR00gQW5hbHlzaXMgb2YgU2Nob29sIExlYWRlciBOZXR3b3JrcyIKYXV0aG9yOiAiSmVubmlmZXIgSG91Y2hpbnMiCmRhdGU6ICdgciBmb3JtYXQoU3lzLnRpbWUoKSwgIiVCICVkLCAlWSIpYCcKb3V0cHV0OiAKICBybWRmb3JtYXRzOjpyZWFkdGhlZG93bjoKICAgIHNlbGZfY29udGFpbmVkOiB0cnVlCiAgICBsaWdodGJveDogdHJ1ZQogICAgZ2FsbGVyeTogZmFsc2UKICAgIGhpZ2hsaWdodDogZGVmYXVsdAogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBlbWJlZF9mb250czogdHJ1ZQogICAgdXNlX2Jvb2tkb3duOiBmYWxzZQpiaWJsaW9ncmFwaHk6IGxpdC9yZWZlcmVuY2VzLmJpYgotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IEZBTFNFKQoKbGlicmFyeShmb250YXdlc29tZSkKbGlicmFyeShrYWJsZUV4dHJhKQpsaWJyYXJ5KGd0c3VtbWFyeSkKYGBgCiMgUFJFUEFSRQoKVGhpcyBzdHVkeSB3YXMgY29tcGxldGVkIGFzIHBhcnQgb2YgdGhlIHN1bW1lciAyMDIxIFNvY2lhbCBOZXR3b3JrIEFuYWx5c2lzIGluIEVkdWNhdGlvbiBjb3Vyc2UgKEVDSSA1ODkpIGF0IE5vcnRoIENhcm9saW5hIFN0YXRlIFVuaXZlcnNpdHkuIFRoZSBjb3Vyc2UgaXMgdGhlIGxhc3Qgb2YgdGhlIHNlcmllcyBvZiBjb3Vyc2VzIG9mZmVyZWQgYXMgcGFydCBvZiB0aGUgTGVhcm5pbmcgQW5hbHl0aWNzIENlcnRpZmljYXRlIFByb2dyYW0uCgpUaGUgUm1hcmtkb3duIGZpbGUgY2FuIGJlIGRvd25sb2FkZWQgZnJvbSB0aGUgY29kZSBmb2xkaW5nIGNvbnRyb2wgYnV0dG9uIGluIHRoZSB1cHBlciByaWdodCBoYW5kIG9mIHRoaXMgcGFnZS4gVGhlIGZ1bGwgUiBTdHVkaW8gcHJvamVjdCBjYW4gYmUgYWNjZXNzIHZpYSBbdGhpcyBHaXRodWIgcmVwb3NpdG9yeV0oaHR0cHM6Ly9naXRodWIuY29tL2plbm5ob3VjaGlucy9FQ0k1ODktU05BKS4gVGhlIHRleHQgZm9yIHRoaXMgY291cnNlIGlzIFtTb2NpYWwgTmV0d29yayBBbmFseXNpcyBhbmQgRWR1Y2F0aW9uOiBUaGVvcnksIE1ldGhvZHMgJgpBcHBsaWNhdGlvbnNdKGh0dHBzOi8vbWV0aG9kcy5zYWdlcHViLmNvbS9ib29rL3NvY2lhbC1uZXR3b3JrLWFuYWx5c2lzLWFuZC1lZHVjYXRpb24pIGZyb20gQGNhcm9sYW4yMDE0LiBUaGUgZGF0YSBmb3IgdGhpcyBwcm9qZWN0IGNhbiBiZSBvYnRhaW5lZCBmcm9tIHRoaXMgdGV4dCdzIGNvbXBhbmlvbiBzaXRlLgoKIyMgQ29udGV4dAoKVGhpcyBpbmRlcGVuZGVudCBhbmFseXNpcyB1c2VzIGRhdGEgZnJvbSBEYWx5J3MgTmV0d29yayBvZiBTY2hvb2wgCkxlYWRlcnMgcHJlc2VudGVkIGluIENoYXB0ZXIgMyBvZiBAY2Fyb2xhbjIwMTQuIFRoZXNlIGRhdGEgd2VyZSBjb2xsZWN0ZWQgYXQgdHdvIHNjaG9vbCBkaXN0cmljdHMgb3ZlciAzIGNvbnNlY3V0aXZlIHllYXJzIGFuZCBpbmNsdWRlOgoKLSAqKmluZGl2aWR1YWwgZGVtb2dyYXBoaWNzKiogKGUuZy4sIGdlbmRlciwgZXRobmljaXR5LCBldGMpCi0gKipuZXR3b3JrIHJlbGF0aW9uc2hpcHMqKiAoZS5nLiwgY29sbGFib3JhdGlvbiwgY29uZmlkZW50aWFsLCBldGMpCiAtICoqZnJlcXVlbmN5IG9mIGludGVyYWN0aW9ucyoqIHdpdGggb3RoZXJzIG9uIGEgZm91ci1wb2ludCBzY2FsZSByYW5naW5nIGZyb20gMSAodGhlIGxlYXN0IGZyZXF1ZW50KSB0byA0ICgx4oCTMiB0aW1lcyBhIHdlZWspCi0gMTggKiplZmZpY2FjeSoqIGl0ZW1zIGJhc2VkIG9uIHRoZSBQcmluY2lwYWwgRWZmaWNhY3kgU2NhbGUgdXNlZCBpbiB0aGUgRGFseSBldCBhbC4gKDIwMTEpIGFuZCBUc2NoYW5uZW4tTW9yYW4gYW5kIEdhcmVpcydzICgyMDA0KSBzdHVkaWVzIGFuZCByYXRlZCAKb24gYSA5LXBvaW50IExpa2VydCBzY2FsZSByYW5naW5nIGZyb20gMSAoTm9uZSBhdCBhbGwpIHRvIDkgKEEgZ3JlYXQgZGVhbCkKLSA4ICoqdHJ1c3QqKiBpdGVtcyByYXRlZCBvbiBhIDctcG9pbnQgTGlrZXJ0IHNjYWxlIHJhbmdpbmcgZnJvbSAxIChTdHJvbmdseSBkaXNhZ3JlZSkgdG8gNyAoU3Ryb25nbHkgYWdyZWUpIG1vZGlmaWVkIGZyb20gVHNjaGFubmVuLU1vcmFuIGFuZCBIb3kgKDIwMDMpLgoKIyMgR3VpZGluZyBRdWVzdGlvbnMgYW5kIE1ldGhvZHMKClRoaXMgc3R1ZHkgZm9jdXNlcyBvbiB0aGUgKipjb25maWRlbnRpYWwgZXhjaGFuZ2VzKioKYmV0d2VlbiBzY2hvb2wgbGVhZGVycyBpbiAqKnllYXIgMSoqIGFuZCBpcyBmcmFtZWQgYnkgdGhlIGZvbGxvd2luZyBxdWVzdGlvbnM6CgoxLiAgRG9lcyBnZW5kZXIgb3Igc29tZSBvdGhlciBpbmRpdmlkdWFsIGF0dHJpYnV0ZSBwcmVkaWN0IGNvbmZpZGVudGlhbAogICAgZXhjaGFuZ2VzIGJldHdlZW4gc2Nob29sIGxlYWRlcnM/CgoyLiAgRG8gc2Nob29sIGxlYWRlcnMgcHJlZmVyIHRvIGNvbmZpZGUgaW4gb3RoZXJzIGF0IHRoZSBzYW1lIGxldmVsIG9mIAogICAgbGVhZGVyc2hpcCAoaS5lLiwgc2Nob29sIG9yIGRpc3RyaWN0KT8KClRoZSBhbmFseXNpcyBlbXBsb3lzICoqRXhwb25lbnRpYWwtZmFtaWx5IFJhbmRvbSBHcmFwaCBNb2RlbHMgKEVSR01zKSoqIHRvIGFuc3dlciB0aGVzZSBxdWVzdGlvbnMuCgoKIyMgUiBQYWNrYWdlcwoKVGhlIGZvbGxvd2luZyBSIHBhY2thZ2VzIHdlcmUgdXNlZCBmb3IgdGhlIGFuYWx5c2VzIGNhcnJpZWQgb3V0IGluIHRoaXMgc3R1ZHkuCgpgYGB7ciBsb2FkLWxpYnMsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRX0KbGlicmFyeShyZWFkeGwpCmxpYnJhcnkoaGVyZSkKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoaWdyYXBoKQpsaWJyYXJ5KHRpZHlncmFwaCkKbGlicmFyeShnZ3JhcGgpCmxpYnJhcnkoZGVsZGlyKQpsaWJyYXJ5KHN0YXRuZXQpCmBgYAoKIyMgSW1wb3J0IHRoZSBEYXRhCgpUaGUgZGF0YSB3ZXJlIGltcG9ydGVkIGZyb20gdGhlIEBjYXJvbGFuMjAxNCB0ZXh0J3MgQ2hhcHRlciA5IEV4Y2VsIGZpbGVzIHByb3ZpZGVkIG9uIHRoZSB0ZXh0IApjb21wYW5pb24gc2l0ZS4gVGhlcmUgYXJlIHR3byBFeGNlbCBmaWxlczoKCi0gKipTY2hvb2xfTGVhZGVyc19EYXRhX0NoYXB0ZXJfOV9lLnhsc3gqKiBwcm92aWRlcyB0aGUgaW5kaXZpZHVhbCBkZW1vZ3JhcGhpYyBkYXRhIGZvciB0aGUgNDMgc2Nob29sIGxlYWRlcnMgaW4gdGhlIG5ldHdvcmsuCi0gKipTY2hvb2xfTGVhZGVyc19EYXRhX0NoYXB0ZXJfOV9jLnhsc3gqKiBwcm92aWRlcyB0aGUgYWRqYWNlbmN5IG1hdHJpeCByZXBvcnRzIG9uICJjb25maWRlbnRpYWwgZXhjaGFuZ2UiIHRpZXMgb2YgdGhlc2UgNDMgc2Nob29sIGxlYWRlcnMgaW4geWVhciAxIG9mIHRoZSBzdHVkeS4KCmBgYHtyIGRhdGEtaW1wb3J0LCBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0V9CmxlYWRlcl9ub2RlcyA8LSByZWFkX2V4Y2VsKGhlcmUoIlByZXNlbnRhdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImRhdGEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTY2hvb2xfTGVhZGVyc19EYXRhX0NoYXB0ZXJfOV9lLnhsc3giKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sX3R5cGVzID0gYygidGV4dCIsICJudW1lcmljIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm51bWVyaWMiLCAibnVtZXJpYyIsICJudW1lcmljIikpCgpsZWFkZXJfbWF0cml4IDwtIHJlYWRfZXhjZWwoaGVyZSgiUHJlc2VudGF0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImRhdGEiLCJTY2hvb2xfTGVhZGVyc19EYXRhX0NoYXB0ZXJfOV9jLnhsc3giKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xfbmFtZXMgPSBGQUxTRSkKYGBgCgojIFdSQU5HTEUKCkkndmUgZ290IGFsbCBteSBsaWJyYXJpZXMgbG9hZGVkIGFuZCB0aGUgZGF0YSBoYXMgYmVlbiBpbXBvcnRlZC4gU28sIGxldCdzIGdvIHdyYW5nbGUgc29tZSBkYXRhLi4uCgpgYGB7ciBkYXRhLWFkdmVudHVyZX0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aCA9ICJodHRwczovL21lZGlhLmdpcGh5LmNvbS9tZWRpYS81aWhmNHlNVjgxeEsvZ2lwaHkuZ2lmIikKYGBgCgojIyBEaWNob3RvbWl6ZSB0aGUgTWF0cml4CgpEaWNob3RvbWl6aW5nIGlzIHJlY29kaW5nIGVkZ2UgdmFsdWVzIHRvIDFzIGFuZCAwcyBzbyB0aGF0IHRoZSB2YWx1ZWQgbWF0cml4IGlzIGEgYmluYXJ5IG1hdHJpeC4gVG8gYWNjb21wbGlzaCB0aGlzLCBJIGZpcnN0IGNyZWF0ZSB0aGUgbWF0cml4IG9iamVjdC4KCmBgYHtyIGRpY2hvdG9taXplLW9uZSwgZWNobz1UUlVFfQpsZWFkZXJfbWF0cml4IDwtIGxlYWRlcl9tYXRyaXggJT4lCiAgYXMubWF0cml4KCkKYGBgCgpUaGVuIEkgZGljaG90b21pemUgaXQgYnkgc2V0dGluZyBsZXNzIGZyZXF1ZW50IHRpZXMgdG8gMCBhbmQgbW9yZSBmcmVxdWVudCB0aWVzIHRvIDEuCgpgYGB7ciBkaWNob3RvbWl6ZS10d28sIGVjaG89VFJVRX0KbGVhZGVyX21hdHJpeFtsZWFkZXJfbWF0cml4IDw9IDJdIDwtIDAKCmxlYWRlcl9tYXRyaXhbbGVhZGVyX21hdHJpeCA+PSAzXSA8LSAxCmBgYAoKTmV4dCwgSSBhZGQgdGhlIG5vZGUgbmFtZXMgYXMgcm93IGFuZCBjb2x1bW4gbmFtZXMgZm9yIHRoZSBwdXJwb3NlIG9mIGdlbmVyYXRpbmcgYW4gZWRnZS1saXN0IGZvciB0aGlzIG5ldHdvcmsuCgpgYGB7ciBkaWNob3RvbWl6ZS10aHJlZSwgZWNobz1UUlVFfQpyb3duYW1lcyhsZWFkZXJfbWF0cml4KSA8LSBsZWFkZXJfbm9kZXMkSUQKY29sbmFtZXMobGVhZGVyX21hdHJpeCkgPC0gbGVhZGVyX25vZGVzJElECmBgYAoKIyMgQ3JlYXRlIE5ldHdvcmsgR3JhcGgKCkluIG9yZGVyIHRvIGV4dHJhY3QgdGhlIGVkZ2UgbGlzdCwgSSB1c2UgdGhlIG1hdHJpeCB0byBjcmVhdGUgYW4gaWdyYXBoIGdyYXBoIG9iamVjdC4KCmBgYHtyIGFkamFjZW5jeS1tYXQsIGVjaG89VFJVRX0KYWRqYWNlbmN5X21hdHJpeCA8LSBncmFwaC5hZGphY2VuY3kobGVhZGVyX21hdHJpeCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlhZyA9IEZBTFNFKQoKY2xhc3MoYWRqYWNlbmN5X21hdHJpeCkKYGBgCgojIyBFZGdlIGxpc3QKQWxsIHRoaXMgc2V0IHVwIGFsbG93cyBtZSB0byBleHRyYWN0IHRoZSBlZGdlLWxpc3QgZnJvbSB0aGUgaWdyYXBoIGdyYXBoIG9iamVjdC4gVGhlIHJlc3VsdCBpcyBhIHNldCBvZiAyNSB0aWVzIGJldHdlZW4gdGhlIHNjaG9vbCBsZWFkZXJzLgoKYGBge3IgZWRnZS1saXN0LCBlY2hvPVRSVUV9CmxlYWRlcl9lZGdlcyA8LSBnZXQuZGF0YS5mcmFtZShhZGphY2VuY3lfbWF0cml4KQoKCmthYmxlKGxlYWRlcl9lZGdlcykKYGBgCgojIyBOZXR3b3JrIEdyYXBoCgpXaXRoIGFuIGVkZ2UgbGlzdCwgSSBjYW4gbm93IGNyZWF0ZSBhIG5ldHdvcmsgZ3JhcGggb2JqZWN0IHVzaW5nIG15IGVkZ2VzIGFuZCBub2Rlcy4gVGhpcyBpcyBzaG93biBpbiB0aGUgZm9sbG93aW5nIGNvZGUgY2h1bmsuCgpgYGB7ciBuZXR3b3JrLWdyYXBoLCBlY2hvPVRSVUV9CgpsZWFkZXJfZ3JhcGggPC0gdGJsX2dyYXBoKGVkZ2VzID0gbGVhZGVyX2VkZ2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVzID0gbGVhZGVyX25vZGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGVkID0gVFJVRSkKCmxlYWRlcl9ncmFwaApgYGAKCkFzIHlvdSBjYW4gc2VlLCB0aGUgcmVzdWx0IGlzIGEgZGlyZWN0ZWQgZ3JhcGggd2l0aCA0MyBub2RlcyAodGhlIHNjaG9vbCBsZWFkZXJzKSBhbmQgMjUgZWRnZXMuIFNpbmNlIHRoZXJlIGFyZSBmZXdlciBlZGdlcyB0aGFuIG5vZGVzLCBpdCBzaG91bGQgYmUgc2FmZSB0byBhc3N1bWUgdGhhdCBzb21lIHNjaG9vbCBsZWFkZXJzIGVpdGhlciBkaWQgbm90IGVuZ2FnZSBpbiBjb25maWRlbnRpYWwgZXhjaGFuZ2VzIGluIHllYXIgMSBvciwgaWYgdGhleSBkaWQsIHRoZXkgZGlkIHNvIHZlcnkgaW5mcmVxdWVudGx5LgoKIyBFWFBMT1JFCgpUaGUgZm9sbG93aW5nIHNlY3Rpb25zIHdpbGwgcHJvdmlkZSBzb21lIGJhc2ljIHN1bW1hcnkgc3RhdGlzdGljcyBvZiB0aGVzZSBkYXRhIGFuZCBhIHNvY2lvZ3JhbSBmb3IgdmlzdWFsaXppbmcgdGhlIG5ldHdvcmsuCgojIyBOb2RlIGRlZ3JlZXMKCkJlZm9yZSBnZXR0aW5nIHRoZSBzdW1tYXJ5IHN0YXRpc2l0aWNzLCBJIGNhbGN1bGF0ZSB0aGUgaW5fZGVncmVlIGFuZCBvdXRfZGVncmVlIG9mIHRoZSBub2RlcyB3aXRoIHRoZSBmb2xsb3dpbmcgY29kZS4KCmBgYHtyIG5vZGUtZGVncmVlc30KbGVhZGVyX21lYXN1cmVzIDwtIGxlYWRlcl9ncmFwaCAlPiUKICBhY3RpdmF0ZShub2RlcykgJT4lCiAgbXV0YXRlKGluX2RlZ3JlZSA9IGNlbnRyYWxpdHlfZGVncmVlKG1vZGUgPSAiaW4iKSkgJT4lCiAgbXV0YXRlKG91dF9kZWdyZWUgPSBjZW50cmFsaXR5X2RlZ3JlZShtb2RlID0gIm91dCIpKQoKbGVhZGVyX21lYXN1cmVzCmBgYAoKIyMgTm9kZSBNZWFzdXJlcwoKV2l0aCB0aGUgaW5fZGVncmVlIGFuZCBvdXRfZGVncmVlIGFkZGVkIHRvIHRoZSBuZXR3b3JrJ3MgbWVhc3VyZXMsIEkgY2FuIGdldCB0aGUgc3VtbWFyeSBvZiB0aGVzZSBtZWFzdXJlcy4KCmBgYHtyIG5vZGUtbWVhc3VyZXN9Cm5vZGVfbWVhc3VyZXMgPC0gbGVhZGVyX21lYXN1cmVzICU+JSAKICBhY3RpdmF0ZShub2RlcykgJT4lCiAgZGF0YS5mcmFtZSgpCgpzdW1tYXJ5KG5vZGVfbWVhc3VyZXMpIApgYGAKCiMjIEJyZWFraW5nIGl0IERvd246IFNjaG9vbCBhbmQgRGlzdHJpY3QgTGV2ZWwgRGVzY3JpcHRpdmVzCgpUaGUgZm9sbG93aW5nIHNlY3Rpb25zIHByb3ZpZGUgZGVzY3JpcHRpdmVzIHN0YXRpc3RpY3MgZm9yIHRoZSBpbiBkZWdyZWUsIG91dCBkZWdyZWUsIHRydXN0LCBhbmQgZWZmaWNhY3kgb2YgdGhlIG5ldHdvcmsgZGVsaW5lYXRlZCBieSBsZXZlbCBvZiBhZG1pbmlzdHJhdGlvbiAoaS5lLiwgc2Nob29sIG9yIGRpc3RyaWN0IGxldmVsKS4KCiMjIyBJbiBEZWdyZWUKCmBgYHtyIGluLWRlZ3JlZX0KaW5fZGVncmVlX3N0YXRzIDwtIG5vZGVfbWVhc3VyZXMgJT4lCiAgZ3JvdXBfYnkoRElTVFJJQ1QuU0lURSkgJT4lCiAgc3VtbWFyaXNlKG4gPSBuKCksCiAgICAgICAgICAgIG1lYW4gPSBtZWFuKGluX2RlZ3JlZSksIAogICAgICAgICAgICBzZCA9IHNkKGluX2RlZ3JlZSkKICAgICAgICAgICAgKSAKCmthYmxlKGluX2RlZ3JlZV9zdGF0cykKYGBgCgojIyMgT3V0IERlZ3JlZQoKYGBge3Igb3V0LWRlZ3JlZX0Kb3V0X2RlZ3JlZV9zdGF0cyA8LSBub2RlX21lYXN1cmVzICU+JQogIGdyb3VwX2J5KERJU1RSSUNULlNJVEUpICU+JQogIHN1bW1hcmlzZShuID0gbigpLAogICAgICAgICAgICBtZWFuID0gbWVhbihvdXRfZGVncmVlKSwgCiAgICAgICAgICAgIHNkID0gc2Qob3V0X2RlZ3JlZSkKICAgICAgICAgICAgKQprYWJsZShvdXRfZGVncmVlX3N0YXRzKQpgYGAKCiMjIyBUcnVzdAoKYGBge3IgdHJ1c3R9CnRydXN0X3N0YXRzIDwtIG5vZGVfbWVhc3VyZXMgJT4lCiAgZ3JvdXBfYnkoRElTVFJJQ1QuU0lURSkgJT4lCiAgc3VtbWFyaXNlKG4gPSBuKCksCiAgICAgICAgICAgIG1lYW4gPSBtZWFuKFRSVVNUKSwgCiAgICAgICAgICAgIHNkID0gc2QoVFJVU1QpCiAgICAgICAgICAgICkKCmthYmxlKHRydXN0X3N0YXRzKQpgYGAKCiMjIyBFZmZpY2FjeQoKYGBge3IgZWZmaWNhY3l9CmVmZmljYWN5X3N0YXRzIDwtIG5vZGVfbWVhc3VyZXMgJT4lCiAgZ3JvdXBfYnkoRElTVFJJQ1QuU0lURSkgJT4lCiAgc3VtbWFyaXNlKG4gPSBuKCksCiAgICAgICAgICAgIG1lYW4gPSBtZWFuKEVGRklDQUNZKSwgCiAgICAgICAgICAgIHNkID0gc2QoRUZGSUNBQ1kpCiAgICAgICAgICAgICkKCmthYmxlKGVmZmljYWN5X3N0YXRzKQpgYGAKCiMjIyBDb21wYXJpc29uIHRvIEBjYXJvbGFuMjAxNAoKRXhhbWluaW5nIHRoZXNlIGRlc2NyaXB0aXZlIHN0YXRpc3RpY3MsIGl0IGFwcGVhcnMgSSBoYXZlIHN1Y2Nlc3NmdWxseSAKcmVwbGljYXRlZCB0aGUgcmVzdWx0cyBzaG93biBpbiBUYWJsZSA5LjEgb2YgQGNhcm9sYW4yMDE0IGZvciBzY2hvb2wgbGVhZGVycyBjb25maWRlbnRpYWwgZXhjaGFuZ2VzIGluIHllYXIgMS4gVGFibGUgOS4xIGlzIHNob3duIGJlbG93LgoKIVtdKGltZy90YWJsZTkuMS5wbmcpCgojIyBWaXN1YWxpemUgdGhlIE5ldHdvcmsKCkFzIHlvdSBzZWUgYmVsb3csIHZpc3VhbGl6aW5nIHRoZSBuZXR3b3JrIGZvciB5ZWFyIDEgbG9va3MgcXVpdGUgYSBiaXQgZGlmZmVyZW50IApmcm9tIHRoZSB5ZWFyIDMgbmV0d29yay4gVGhlcmUgYXJlICoqZmFyIGZld2VyIGNvbmZpZGVudGlhbCBleGNoYW5nZXMgaW4geWVhciAxKiouCkFkZGl0aW9uYWxseSwgY29sb3JpbmcgdGhlIG5vZGVzIGJ5IGdlbmRlciByZXZlYWxzIHRoYXQgdGhlIGdyb3VwaW5ncyBvZiBjb25maWRlbnRpYWwgCmV4Y2hhbmdlcyBkb24ndCBhcHBlYXIgdG8gY29uc2lzdCBvZiBhIHNpbmdsZSBnZW5kZXIuIE1vcmVvdmVyLCB0aGUgbm9kZSBzaGFwZXMgCihzcXVhcmUgZm9yIGRpc3RyaWN0LWxldmVsIGFuZCBjaXJjbGUgZm9yIHNjaG9vbC1sZXZlbCBsZWFkZXIpIGFwcGVhciB0byBpbmRpY2F0ZSB0aGF0IHRoZSBncm91cGluZ3MgCmNvbnNpc3Qgb2YgZWl0aGVyIGEgbWFqb3JpdHkgb2YgZGlzdHJpY3QtbGV2ZWwgbGVhZGVycyBvciBzY2hvb2wtbGV2ZWwgbGVhZGVycy4gVGhpcyAKc3VnZ2VzdHMgdGhhdCBhZG1pbmlzdHJhdGlvbiBsZXZlbCBtYXkgYmUgaW1wb3J0YW50IGluIHllYXIgMSBjb25maWRlbnRpYWwgbmV0d29ya3MuIApJJ2xsIHRha2UgdGhpcyBpbnRvIGNvbnNpZGVyYXRpb24gYXMgSSB1c2UgRVJHTSB0byBtb2RlbCB0aGUgbmV0d29yayBkYXRhLgoKYGBge3Igc29jaW9ncmFtLCBlY2hvPVRSVUV9CmdncmFwaChsZWFkZXJfbWVhc3VyZXMsIGxheW91dCA9ICJmciIpICsgCiAgZ2VvbV9ub2RlX3BvaW50KGFlcyhzaXplID0gb3V0X2RlZ3JlZSwKICAgICAgICAgICAgICAgICAgICAgIGNvbG91ciA9IGZhY3RvcihNQUxFKSwKICAgICAgICAgICAgICAgICAgICAgIGZpbGwgPSBmYWN0b3IoTUFMRSkpLAogICAgICAgICAgICAgICAgICBzaGFwZSA9IG5vZGVfbWVhc3VyZXMkRElTVFJJQ1QuU0lURSArIDIxLCBzaG93LmxlZ2VuZCA9IFRSVUUpICsKICBnZW9tX25vZGVfdGV4dChhZXMobGFiZWwgPSBJRCwKICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IDEuNSksIAogICAgICAgICAgICAgICAgICAgICByZXBlbD1UUlVFLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgZ2VvbV9lZGdlX2xpbmsoYXJyb3cgPSBhcnJvdyhsZW5ndGggPSB1bml0KDEsICdtbScpKSwgCiAgICAgICAgICAgICAgICAgZW5kX2NhcCA9IGNpcmNsZSgyLCAnbW0nKSwKICAgICAgICAgICAgICAgICBhbHBoYSA9IC4zKSArIAogIHRoZW1lX2dyYXBoKCkKYGBgCgojIE1PREVMCgpTZXR0aW5nIHVwIHRvIHBlcmZvcm0gYW4gRVJHTSwgSSBjcmVhdGUgYSBuZXR3b3JrIG9iamVjdCB3aXRoIHRoZXNlIGVkZ2VzIGFuZCBub2Rlcy4gVGhlIHJlc3VsdCBpcyBhIGRpcmVjdGVkIG5ldHdvcmsgd2l0aCA0MyBub2RlcyAoc2Nob29sIGxlYWRlcnMpIGFuZCAyNSBlZGdlcy4KYGBge3IgbmV0d29ya30KbGVhZGVyX25ldHdvcmsgPC0gYXMubmV0d29yayhsZWFkZXJfZWRnZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVydGljZXMgPSBsZWFkZXJfbm9kZXMpCgpsZWFkZXJfbmV0d29yawpgYGAKCiMjIEVSR00KClRvIGFkZHJlc3MgbXkgZ3VpZGluZyBxdWVzdGlvbnMsIEkgcmFuIHRoZSBFUkdNIHdpdGggYWxsIHRoZSBpbmRpdmlkdWFsIGF0dHJpYnV0ZXMgYXMgd2VsbCBhcyB0aGUgZ2VvbWV0cmljYWxseS13ZWlnaGVkIGVkZ2V3aXNlIHNoYXJlZCBwYXJ0bmVyIChHV0VTUCkgdGVybSBmb3IgdHJhbnNpdGl2aXR5LgpgYGB7ciBlcmdtLCBtZXNzYWdlPUZBTFNFLCBjYWNoZT1UUlVFfQpzZXQuc2VlZCg1ODkpCm15X2VyZ20gPC0gZXJnbShsZWFkZXJfbmV0d29yayB+IGVkZ2VzICsKICAgICAgICAgICAgICAgICBtdXR1YWwgKwogICAgICAgICAgICAgICAgIGd3ZXNwKDAuMjUsIGZpeGVkPVQpICsKICAgICAgICAgICAgICAgICBub2RlZmFjdG9yKCdNQUxFJykgKwogICAgICAgICAgICAgICAgIG5vZGVjb3YoJ0VGRklDQUNZJykgKwogICAgICAgICAgICAgICAgIG5vZGVjb3YoJ1RSVVNUJykgKwogICAgICAgICAgICAgICAgIG5vZGVtYXRjaCgnRElTVFJJQ1QvU0lURScpCiAgICAgICAgICAgICAgICkKCnN1bW1hcnkobXlfZXJnbSkKYGBgCgpXaGlsZSBnZW5kZXIsIGVmZmljYWN5LCBhbmQgdHJ1c3QgZG8gbm90IGFwcGVhciB0byBiZSBzaWduaWZpY2FudCBwcmVkaWN0b3JzIG9mIApjb25maWRlbnRpYWwgZXhjaGFuZ2VzIGluIHllYXIgMSwgdGhlIEdXRVNQIGFuZCB0aGUgbGV2ZWwgb2YgYWRtaW5pc3RyYXRpb24gdGVybXMgYXJlIHNpZ25pZmljYW50IGlzIHRoaXMgbW9kZWwuCgoKIyMgTW9kZWwgRml0CgpMZXQncyBqdXN0IHRha2UgYSBsb29rIGF0IHRoZSBmaXQgb2YgdGhpcyBtb2RlbCB1c2luZyB0aGUgYGdvZigpYCBmdW5jdGlvbiBhbmQgcnVubmluZyAKc29tZSBgbWNtYy5kaWFnbm9zdGljcygpYC4KCiMjIyBHb29kbmVzcyBvZiBGaXQKCk92ZXJhbGwsIHRoZSByZXN1bHRzIG9mIHRoZSBgZ29mKClgIGZ1bmN0aW9uIHNob3cgdGhhdCB0aGlzIG1vZGVsIGZpdHMgcmVhc29uYWJseSB3ZWxsLiBUaGF0IGlzLCAKd2l0aCB0aGUgZXhjZXB0aW9uIG9mIHRoZSBtdXR1YWwgdGVybSB3aGljaCBpc24ndCBzdXJwcmlzaW5nIGdpdmVuIHRoZSBwLXZhbHVlLgoKYGBge3IgZXJnbS1maXQsIGVjaG89VFJVRX0KbXlfZXJnbV9nb2YgPC0gZ29mKG15X2VyZ20pCgpwbG90KG15X2VyZ21fZ29mKQpgYGAKCiMjIyBNQ01DIERpYWdub3N0aWNzCgpOZXh0LCBJIGV4YW1pbmUgdGhlIE1vbnRlLUNhcmxvIE1hcmtvdiBDaGFpbiAoTUNNQykgZGlhZ25vc3RpY3MgZm9yIHRoaXMgbW9kZWwuIAoKYGBge3IgbWNtYy1kaWFnLCBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0V9Cm1jbWMuZGlhZ25vc3RpY3MobXlfZXJnbSkKYGBgCgpPdmVyYWxsLCB0aGUgZGlhZ25vc3RpY3MgYXJlIGEgbGl0dGxlIGRpZmZpY3VsdCB0byBpbnRlcnByZXQgYnV0IGFsc28gYXBwZWFyIHRvIAppbmRpY2F0ZSB0aGF0IHRoZSBtb2RlbCBpcyBhIHJlYXNvbmFibGUgZml0LgoKIyBDT01NVU5JQ0FURQoKVGhpcyBzdHVkeSB3YXMgZnJhbWVkIGJ5IHRoZSBmb2xsb3dpbmcgcXVlc3Rpb25zOgoKMS4gIERvZXMgZ2VuZGVyIG9yIHNvbWUgb3RoZXIgaW5kaXZpZHVhbCBhdHRyaWJ1dGUgcHJlZGljdCBjb25maWRlbnRpYWwKICAgIGV4Y2hhbmdlcyBiZXR3ZWVuIHNjaG9vbCBsZWFkZXJzPwoKMi4gIERvIHNjaG9vbCBsZWFkZXJzIHByZWZlciB0byBjb25maWRlIGluIG90aGVycyBhdCB0aGUgc2FtZSBsZXZlbCBvZiAKICAgIGxlYWRlcnNoaXAgKGkuZS4sIHNjaG9vbCBvciBkaXN0cmljdCk/CgpBbnN3ZXJpbmcgcXVlc3Rpb24gMSBiYXNlZCBvbiB0aGUgcmVzdWx0cyBpbiB0aGUgcHJldmlvdXMgc2VjdGlvbnMsIGl0IHdvdWxkIGFwcGVhciB0aGF0IHRoZSBvbmx5IGluZGl2aWR1YWwgCmF0dHJpYnV0ZSB0aGF0IHByZWRpY3RzIGNvbmZpZGVudGlhbCBleGNoYW5nZXMgaW4geWVhciAxIGlzIHdoZXRoZXIgYSBzY2hvb2wgbGVhZGVyIAppcyBhdCB0aGUgc2Nob29sIG9yIGRpc3RyaWN0IGxldmVsLiBNb3Jlb3ZlciwgY29uZmlkZW50aWFsIGV4Y2hhbmdlcyBhbHNvIGFwcGVhciB0byBiZSAKc2lnbmlmaWNhbnRseSBpbXBhY3RlZCBieSB0cmFuc2l0aXZpdHkgcmVwcmVzZW50ZWQgYnkgdGhlIGdlb21ldHJpY2FsbHktd2VpZ2hlZCBlZGdld2lzZSAKc2hhcmVkIHBhcnRuZXIgdGVybSAoaS5lLiwgImZyaWVuZCBvZiBhIGZyaWVuZCIgcGhlbm9tZW5vbikuIFRoZXNlIHJlc3VsdHMgc3VnZ2VzdCB0aGF0LCBhdCBsZWFzdCAKZm9yIHllYXIgMSwgc2Nob29sIGxlYWRlcnMgYXBwZWFyIHRvIHByZWZlciB0byBjb25maWRlIGluIG90aGVycyBhdCB0aGUgc2FtZSBsZXZlbCAKb2YgYWRtaW5pc3RyYXRpb24uCgojIEFCT1VUIFRIRSBBVVRIT1IKIVtdKGltZy9qZW5uLmpwZyl7d2lkdGg9IjkwcHgiIHN0eWxlPSJmbG9hdDogbGVmdDsgbWFyZ2luLXJpZ2h0OiAzMHB4OyBtYXJnaW4tdG9wOiA1cHg7In0KSmVubmlmZXIgSG91Y2hpbnMgaXMgRGlyZWN0b3Igb2YgVGVjaG5vbG9neSBQcm9ncmFtcyBhdCB0aGUgW0ZyaWRheSBJbnN0aXR1dGUgZm9yIEVkdWN0aW9uYWwgSW5ub3ZhdGlvbl0oaHR0cDovL2ZpLm5jc3UuZWR1KSAKYW5kIGEgZG9jdG9yYWwgY2FuZGlkYXRlIGluIExlYXJuaW5nIERlc2lnbiBhbmQgVGVjaG5vbG9neSBhdCBOb3J0aCBDYXJvbGluYSAKU3RhdGUgVW5pdmVyc2l0eS4gSGVyIHJlc2VhcmNoIGV4YW1pbmVzIHN0dWRlbnRzJyB1c2Ugb2YgY29tcHV0YXRpb25hbCB0aGlua2luZyBhbmQgdGhlIAplZmZlY3RpdmUgdXNlIG9mIGluc3RydWN0aW9uYWwgdGVjaG5vbG9neSB0byBkZWVwZW4gY29uY2VwdHVhbCB1bmRlcnN0YW5kaW5nIGluIGJvdGggZm9ybWFsIGFuZCAKaW5mb3JtYWwgSy0xMiBsZWFybmluZyBlbnZpcm9ubWVudHMuIAoKKllvdSBjYW4gbGVhcm4gbW9yZSBhYm91dCBKZW5uaWZlciBhbmQgaGVyIHdvcmsgYnkgW3Zpc2l0aW5nIGhlciB3ZWJzaXRlXShodHRwczovL2plbm5pZmVya2hvdWNoaW5zLmNvbSkuIFlvdSBjYW4gYWxzbyBmb2xsb3cgaGVyIG9uIGByIGZvbnRhd2Vzb21lOjpmYV9pKCd0d2l0dGVyJylgOiBbXEBUb29Td2VldEdlZWtdKGh0dHBzOi8vdHdpdHRlci5jb20vVG9vU3dlZXRHZWVrKSoKCiMgR0VUIFRIRSBQUk9KRUNUIENPREUKCklmIHlvdSdkIGxpa2UgdG8gbGVhcm4gbW9yZSBhYm91dCB0aGUgdGVjaG5pcXVlcyB1c2VkIGluIHRoaXMKYW5hbHlzaXMgKGluY2x1ZGluZyB0aGUgUm1hcmtkb3duIHRlY2huaXF1ZXMgdXNlZCBpbiB0aGUgd3JpdGUgdXApLCB0aGVuIHlvdSBjYW4gZ2V0IHRoZSBSIHByb2plY3QgZnJvbSBteQpHaXRodWIgcmVwbzo8YnIgLz4KCjxodHRwczovL2dpdGh1Yi5jb20vamVubmhvdWNoaW5zL0VDSTU4OS1TTkE+CgojIFRIRSBFTkQgT0YgQU4gRVJBCgpUaGlzIGlzIHRoZSBiaXR0ZXJzd2VldCBlbmQgb2YgbXkgY291cnNld29yayBpbiB0aGUgTGVhcm5pbmcgQW5hbHl0aWNzIENlcnRpZmljYXRlIFByb2dyYW0gYXQgTkMgU3RhdGUgKGFuZCB1bHRpbWF0ZWx5LCBteSBkb2N0b3JhbCBwcm9ncmFtIGNvdXJzZXdvcmsgYXMgd2VsbCkuIEkgaGF2ZSBlbmpveWVkIHRoZXNlIGNvdXJzZXMgYW5kIHRoZSBsZWFybmluZyBjb21tdW5pdHkgSSd2ZSBnYWluZWQgaW4gdGhlbSwgYnV0IGFtIHZlcnkgbXVjaCBsb29raW5nIGZvcndhcmQgdG8gY29tcGxldGVseSBteSBkaXNzZXJ0YXRpb24gYW5kIGdyYWR1YXRpbmcuCgpgYGB7ciBnb29kYnllfQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhwYXRoID0gImh0dHBzOi8vbWVkaWEuZ2lwaHkuY29tL21lZGlhLzNvNk1ia0ZGaENrUU9hZ0RUTy9naXBoeS5naWYiKQpgYGAKCiMgUkVGRVJFTkNFUyA=